﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Interaction logic for CoreSymbolInserter.xaml
    /// </summary>
    public partial class CoreSymbolInserter : UserControl
    {
        #region Constructors

        /// <summary>
        /// Creates a new <see cref="CoreSymbolInserter"/> instance.
        /// </summary>
        public CoreSymbolInserter()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers
        
        /// <summary>
        /// Occurs when the user clicks the mouse button on the inserter.
        /// </summary>
        /// <param name="sender">Object where the event handler is attached</param>
        /// <param name="e">Event data</param>
        private void UserControl_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            try
            {
                inserter.InsertSymbol();
            }
            catch (Exception)
            {
                System.Media.SystemSounds.Beep.Play();
            }
        }

        /// <summary>
        /// Occurs when the data context (visualized inserter) of the control has changed.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (inserter != null)
                inserter.PropertyChanged -= inserter_PropertyChanged;

            inserter = (ViewModel.Elements.CWNotation.CoreSymbolInserter)DataContext;

            if (inserter != null)
                inserter.PropertyChanged += new PropertyChangedEventHandler(inserter_PropertyChanged);

            SetVisualization();
        }

        /// <summary>
        /// Occurs when a property of the visualized inserter has changed.
        /// </summary>
        /// <param name="sender">Object that has sent the event</param>
        /// <param name="e">Event data</param>
        private void inserter_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ActiveStaff" || e.PropertyName == "SymbolType" || e.PropertyName == "BasicDuration")
                SetVisualization();
            else if (e.PropertyName == "IsSymbolVisible")
            {
                if (inserter.IsSymbolVisible)
                {
                    CaptureMouse();
                    PART_InserterSymbol.Visibility = System.Windows.Visibility.Visible;
                    PART_Ledgers.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    ReleaseMouseCapture();
                    PART_InserterSymbol.Visibility = System.Windows.Visibility.Collapsed;
                    PART_Ledgers.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Sets the symbol and margin of the <see cref="PART_InserterSymbol"/>.
        /// </summary>
        private void SetVisualization()
        {
            if (inserter.ActiveStaff == null)
                return;

            double spaceSize = inserter.ActiveStaff.SpaceSize;

            switch (inserter.SymbolType)
            {
                case ViewModel.Elements.CWNotation.InsertedSymbolType.BassClef:
                    PART_InserterSymbol.Text = "?";
                    PART_InserterSymbol.Margin = new Thickness(0, - 2.5 * spaceSize, 0, 0);
                    break;
                case ViewModel.Elements.CWNotation.InsertedSymbolType.TenoreClef:
                    PART_InserterSymbol.Text = "B";
                    PART_InserterSymbol.Margin = new Thickness(0, -3.5 * spaceSize, 0, 0);
                    break;
                case ViewModel.Elements.CWNotation.InsertedSymbolType.TrebleClef:
                    PART_InserterSymbol.Text = "&";
                    PART_InserterSymbol.Margin = new Thickness(0, - 4.5 * spaceSize, 0, 0);
                    break;
                case ViewModel.Elements.CWNotation.InsertedSymbolType.Note:
                    PART_InserterSymbol.Text = "Ï";
                    PART_InserterSymbol.Margin = new Thickness(0, -5.5 * spaceSize, 0, 0);
                    break;
                case ViewModel.Elements.CWNotation.InsertedSymbolType.Rest:
                    switch (inserter.BasicDuration)
                    {
                        case 128:
                            PART_InserterSymbol.Text = "î";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 5.5, 0, 0);
                            break;
                        case 64:
                            PART_InserterSymbol.Text = "î";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 5.0, 0, 0);
                            break;
                        case 32:
                            PART_InserterSymbol.Text = "Î";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 5.25, 0, 0);
                            break;
                        case 16:
                            PART_InserterSymbol.Text = "ä";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 5.5, 0, 0);
                            break;
                        case 8:
                            PART_InserterSymbol.Text = "Å";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 4.5, 0, 0);
                            break;
                        case 4:
                            PART_InserterSymbol.Text = "¨";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 4.5, 0, 0);
                            break;
                        case 2:
                            PART_InserterSymbol.Text = "ô";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 4.5, 0, 0);
                            break;
                        case 1:
                            PART_InserterSymbol.Text = "å";
                            PART_InserterSymbol.Margin = new Thickness(0, -spaceSize * 4.5, 0, 0);
                            break;
                    }
                    break;
            }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the visualized inserter.
        /// </summary>
        private ViewModel.Elements.CWNotation.CoreSymbolInserter inserter;

        #endregion
    }
}
